import random

class Existence(object):
    def __init__(self, maxcycles):
        self.maxcycles = maxcycles
        self.initialiseVars()
        self.Existence()

    def initialiseVars(self):
        self.e1 = "experiment one"
        self.e2 = "experiment two"
        self.experiments = [self.e1,self.e2]
        self.r1 = "result one"
        self.r2 = "result two"
        self.results = []
        self.UNKNOWN = "unknown"
        self.BORED = "bored"
        self.FRUSTRATED = "frustrated"
        self.SELF_SATISFIED = "self-satisfied"
        self.tupleRecord = {}  # {experiment: [result], experiment: [result])
        self.mood = self.UNKNOWN

    def pickOtherExperiment(self,experiment):
        ''' A placeholder until a more intelligent Algorithm is implemeted. '''
        if self.mood != self.SELF_SATISFIED: 
            return random.choice(self.experiments) 
        return experiment 

    def anticipate(self,experiment):
        ''' A placeholder until a more intelligent Algorithm is implemeted. '''
        if experiment in self.tupleRecord:
            return random.choice(self.tupleRecord[experiment])
        elif len(self.results) > 0:
            return random.choice(self.results)
        else: 
            return self.UNKNOWN


    def recordTuple(self,experiment,result):
        ''' Rename this sometime '''
        if experiment not in self.tupleRecord:
            self.tupleRecord[experiment] = []
        self.tupleRecord[experiment].append(result)
        if result not in self.results:
            self.results.append(result)

    def Existence(self):
        stillLiving = True
        cycle = 0
        experiment = self.e1
        selfSatisfiedDuration = 0
        anticipatedResult = self.UNKNOWN
        result = self.UNKNOWN

        while stillLiving:
            cycle += 1
            if (self.mood == self.BORED):
                selfSatisfiedDuration = 0

            experiment = self.pickOtherExperiment(experiment)
            anticipatedResult = self.anticipate(experiment)

            if (experiment == self.e1):
                result = self.r1
            else:
                result = self.r2

            self.recordTuple(experiment, result)

            if (result == anticipatedResult):
                self.mood = self.SELF_SATISFIED
                selfSatisfiedDuration += 1
            else:
                self.mood = self.FRUSTRATED
                selfSatisfiedDuration = 0

            if (selfSatisfiedDuration > 3):
                self.mood = self.BORED
                selfSatisfiedDuration = 0

            print "%3d: %12s | %10s | %5s" % (cycle, experiment, result, self.mood)
            if cycle == self.maxcycles: break


if __name__ == "__main__":
    maxcycles = 20      # number of cycles to run
    run1 = Existence(maxcycles)

